package controlador;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;
import modelo.bd.dao.GenericoDAO;
import modelo.bd.excepcion.DAOException;
import modelo.dominio.Solicitud;
import modelo.servicio.Anexos;
import modelo.servicio.Facturas;
import modelo.servicio.Solicitudes;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;

public class SolicitudControlador extends HttpServlet {

    private String accion;
    private String usuario;
    private StringBuilder html;
    private DateFormat df = new SimpleDateFormat("dd/MM/yyyy");

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        html = new StringBuilder("");
        accion = request.getParameter("ac") != null
                ? request.getParameter("ac") : "";
        usuario = request.getSession().getAttribute("sUsuario") != null
                ? request.getSession().getAttribute("sUsuario").toString() : "";
        PrintWriter out = null;
        if (!accion.equals("dl")) {
            out = response.getWriter();
        }
        try {
            if (accion.compareToIgnoreCase("ls") == 0) {
                String desde = request.getParameter("txt_desde");
                String hasta = request.getParameter("txt_hasta");
                List<Solicitud> historicos = Solicitudes.instancia().porRango(desde, hasta);
                request.setAttribute("solicitudes", historicos);
                getServletContext().getRequestDispatcher("/front?v=11&ac=0").forward(request, response);
            } else if (accion.compareToIgnoreCase("pe") == 0) {
                //List<Solicitud> solicitudesPendientes = Solicitudes.instancia().todos(usuario);
            } else if (accion.compareToIgnoreCase("sv") == 0) {
                String claveFlujo = request.getParameter("clvf");
                String clavePaso = request.getParameter("clvp");
                String claveEvento = request.getParameter("clve");
                String comentarios = request.getParameter("txa_comentarios") != null
                        ? request.getParameter("txa_comentarios") : "";
                String proveedor = request.getParameter("cmb_proveedor");

                String folioFactura = request.getParameter("cmb_factura");
                String montoFactura = request.getParameter("txt_monto_fact");
                String fechaFactura = request.getParameter("txt_fecha_fact");
                String concepto = request.getParameter("txa_concepto");
                String nombreAnexo = request.getParameter("txt_nombre_anexo");
                Date fechaFact = df.parse(fechaFactura);
                String resultado = "Error";
                resultado = Solicitudes.instancia().procesar(claveFlujo, 0, clavePaso,
                        Double.parseDouble(montoFactura), claveEvento, comentarios, null, usuario);
                long folio;
                try {
                    folio = Long.parseLong(resultado);
                    Facturas.instancia().agregar(claveFlujo, folio, proveedor, folioFactura, fechaFact,
                            Double.parseDouble(montoFactura), concepto, comentarios, usuario);
                    html.append("La solicitud ha sido creada correctamente con el folio: ")
                            .append(folio);
                    html.append("<script type='text/javascript'>")
                            .append("$('#tabs').tabs('load', 0).delay(1000).slideUp(300).fadeIn(400);")
                            .append("</script>");
                } catch (Exception e) {
                    html.append("Ha ocurrido el siguiente error: ")
                            .append(resultado);
                }
            } else if (accion.compareToIgnoreCase("ed") == 0) {
                
            } else if (accion.compareToIgnoreCase("ap") == 0) {
                String claveFlujo = request.getParameter("clvf");
                String clavePaso = request.getParameter("clvp");
                String claveEvento = request.getParameter("cmb_evento");
                String claveCausa = request.getParameter("cmb_causa");
                long folio = Long.parseLong(request.getParameter("folio"));
                String comentarios = request.getParameter("txa_comentarios") != null
                        ? request.getParameter("txa_comentarios") : "";
                String resultado = Solicitudes.instancia().procesar(claveFlujo, folio, clavePaso,
                        0, claveEvento, comentarios, claveCausa, usuario);
                if (resultado.equals("" + folio)) {
                    html.append("La solicitud ha sido procesada correctamente: ");
                    html.append("<script type='text/javascript'>")
                            .append("$('#tabs').tabs('load', 0).slideUp(300).delay(1000).fadeIn(400);")
                            .append("</script>");
                } else {
                    html.append("Ha ocurrido el siguiente error: ").append(resultado);
                }
            } else if (accion.equals("dl")) {
                try {
                    String arcc = request.getParameter("src");
                    response.setContentType("APPLICATION/OCTET-STREAM");
                    int desde = arcc.lastIndexOf("\\") > 0 ? arcc.lastIndexOf("\\") : arcc.length();
                    String nombreArchivo = arcc.substring(desde + 1, arcc.length());
                    response.setHeader("Content-Disposition", "Attachment;Filename=\"" + nombreArchivo + "\"");
                    ServletOutputStream outF = response.getOutputStream();
                    InputStream in = null;
                    if (UsuarioControlador.isCIFS()) {
                        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(UsuarioControlador.getUsuarioCIFS());
                        String path = "smb:" + arcc.replace("\\", "/");
                        SmbFile sFile = new SmbFile(path, auth);
                        in = sFile.getInputStream();
                    } else {
                        File fichero = new File(arcc);
                        in = new FileInputStream(fichero);
                    }
                    byte[] buffer = new byte[UsuarioControlador.getTamanioBuffer()];
                    int read;
                    while ((read = in.read(buffer, 0, UsuarioControlador.getTamanioBuffer())) != -1) {
                        outF.write(buffer, 0, read);
                    }
                    outF.close();
                    in.close();
                } catch (Exception e) {
                    out.print(e.getMessage());
                }
            }
            //EMPIEZA LA CARGA DEL ARCHIVO
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (isMultipart) {
                try {
                    String claveFlujo = "";
                    String clavePaso = "";
                    String claveEvento = "";
                    String comentarios = "";
                    String proveedor = "";

                    String folioFactura = "";
                    String montoFactura = "";
                    String fechaFactura = "";
                    String concepto = "";
                    String resultado;

                    String nombresAnexo[] = new String[UsuarioControlador.getNumeroAnexos()];
                    String rutasAnexo[] = new String[UsuarioControlador.getNumeroAnexos()];
                    int contadorAnexos = 0;

                    String nombreArchivo = "";
                    String rutaCompletaArchivo = "";

                    List<FileItem> items = null;
                    DiskFileItemFactory factory = new DiskFileItemFactory();
                    factory.setSizeThreshold(10240);
                    factory.setRepository(new File(UsuarioControlador.getDirectorioTemporal()));
                    ServletFileUpload upload = new ServletFileUpload(factory);
                    try {
                        items = upload.parseRequest(request);
                    } catch (FileUploadException ex) {
                        out.println("Error de Parsing:" + ex.getMessage());
                    }
                    for (int i = 0; i < items.size(); i++) {
                        FileItem item = (FileItem) items.get(i);
                        if (item.isFormField()) {
                            if (item.getFieldName().equals("clvf")) {
                                claveFlujo = item.getString();
                            } else if (item.getFieldName().equals("clvp")) {
                                clavePaso = item.getString();
                            } else if (item.getFieldName().equals("clve")) {
                                claveEvento = item.getString();
                            } else if (item.getFieldName().equals("cmb_proveedor")) {
                                proveedor = item.getString();
                            } else if (item.getFieldName().equals("cmb_factura")) {
                                folioFactura = item.getString();
                            } else if (item.getFieldName().equals("txt_monto_fact")) {
                                montoFactura = item.getString();
                                montoFactura = montoFactura.replace(",", "");
                            } else if (item.getFieldName().equals("txt_fecha_fact")) {
                                fechaFactura = item.getString();
                            } else if (item.getFieldName().equals("txa_concepto")) {
                                concepto = item.getString();
                            } else if (item.getFieldName().equals("txa_comentarios")) {
                                comentarios = item.getString();
                            } else if (item.getFieldName().indexOf("txt_nombre_anexo") != -1) {
                                nombresAnexo[contadorAnexos] = item.getString() == null ||
                                        item.getString().equals("")
                                        ? "Anexo " + (contadorAnexos + 1) : item.getString();
                            }
                        } else {
                            String fileName = item.getName();
                            if (!fileName.equals("")) {
                                int desde = fileName.lastIndexOf(".") > 0
                                        ? fileName.lastIndexOf(".")
                                        : fileName.length();
                                String ext = fileName.substring(desde, fileName.length());
                                DateFormat df2 = new SimpleDateFormat("dd_MM_yyyy_HH_mm_ss");
                                nombreArchivo = "A"+(contadorAnexos+1)+"_"+df2.format(new Date());

                                nombreArchivo += ext;
                                rutaCompletaArchivo = UsuarioControlador.getDirectorioCarga() + claveFlujo.replace("'", "_") + "\\" + nombreArchivo;
                                rutasAnexo[contadorAnexos] = rutaCompletaArchivo;
                                contadorAnexos++;
                                OutputStream outp = null;
                                if (UsuarioControlador.isCIFS()) {
                                    NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(UsuarioControlador.getUsuarioCIFS());
                                    String path = "smb:" + rutaCompletaArchivo.replace("\\", "/");
                                    SmbFile ruta = new SmbFile(("smb:" + UsuarioControlador.getDirectorioCarga() + claveFlujo.replace("'", "_") + "\\").replace("\\", "/"), auth);
                                    if (!ruta.exists()) {
                                        ruta.mkdir();
                                    }
                                    SmbFile sFile = new SmbFile(path, auth);
                                    outp = new SmbFileOutputStream(sFile);
                                } else {
                                    File ruta = new File(UsuarioControlador.getDirectorioCarga());
                                    if(!ruta.exists())
                                        ruta.mkdir();
                                    File fichero = new File(rutaCompletaArchivo);
                                    outp = new FileOutputStream(fichero);
                                }
                                InputStream in = item.getInputStream();
                                byte[] buffer = new byte[UsuarioControlador.getTamanioBuffer()];
                                int read;
                                while ((read = in.read(buffer, 0, UsuarioControlador.getTamanioBuffer())) != -1) {
                                    outp.write(buffer, 0, read);
                                }
                                in.close();
                                outp.close();
                            } else {
                                //no adjunto el archivo
                            }
                        }
                    }//del for recorre los item del formulario
                    Date fechaFact = df.parse(fechaFactura);
                    resultado = Solicitudes.instancia().procesar(claveFlujo, 0, clavePaso,
                            Double.parseDouble(montoFactura), claveEvento, comentarios, null, usuario);
                    long folio;
                    try {
                        folio = Long.parseLong(resultado);
                        Facturas.instancia().agregar(claveFlujo, folio, proveedor, folioFactura, fechaFact,
                                Double.parseDouble(montoFactura), concepto, comentarios, usuario);
                        /*esta para tomar el id de la factura*/
                        GenericoDAO dao = new GenericoDAO();
                        String condicionMax = "fapr_prpo_numero = " + proveedor;
                        long idFactura = dao.selectMax("sil_facturas_proveedor", "fapr_numero", condicionMax);
                        --idFactura;
                        /*se resta uno ya que regresa el siguiente consecutivo*/
                        for (int j = 0; j < rutasAnexo.length; j++) {
                            if (!(rutasAnexo[j] == null || rutasAnexo[j].equals("")) ) {
                                String nom = nombresAnexo[j];
                                String rut = rutasAnexo[j];
                                Anexos.instancia().agregar(claveFlujo, folio, proveedor,
                                        idFactura, nom, rut, usuario);
                            }
                        }
                        html.append("La solicitud ha sido creada correctamente con el folio: ")
                                .append(folio);
                        html.append("<script type='text/javascript'>")
                                .append("$('#tabs').tabs('load', 0).slideUp(300).delay(1000).fadeIn(400);")
                                .append("</script>");
                    } catch (Exception e) {
                        html.append("Ha ocurrido el siguiente error: ")
                                .append(resultado);
                    }
                    response.sendRedirect(getServletContext().getContextPath());
                } catch (Exception ex) {
                    out.println("Error al guardar el anexo: " + ex.getMessage());
                }
            }
            /**
             * **TERMINA LA CARGA DEL ARCHIVO****
             */
            out.println(html);
        } catch (DAOException dex) {
            out.println("Error en la base de datos: " + dex.getMessage() + "<br/>" + dex.getLocalizedMessage());
        } catch (ParseException ex) {
            out.println("Error de fechas: " + ex.getMessage() + "<br/>" + ex.getLocalizedMessage());
        } catch (Exception ex) {
            out.println("Error en server: " + ex.getMessage() + "<br/>" + ex.getLocalizedMessage());
        } finally {
            out.close();
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}
